package hu.bme.mit.androtext.generator.util;

import hu.bme.mit.androtext.data.androData.DataTypeRef;
import hu.bme.mit.androtext.data.androData.EntityTypeRef;
import hu.bme.mit.androtext.data.androData.Feature;
import hu.bme.mit.androtext.data.androData.TypeRef;
import hu.bme.mit.androtext.generator.AppGenerationException;
import hu.bme.mit.androtext.generator.IAppGenerator;
import hu.bme.mit.androtext.generator.app.AndroidConstants2;
import hu.bme.mit.androtext.gui.androGui.AndroGuiRoot;
import hu.bme.mit.androtext.gui.androGui.LayoutStyle;
import hu.bme.mit.androtext.gui.androGui.Preference;
import hu.bme.mit.androtext.gui.androGui.PreferenceCategory;
import hu.bme.mit.androtext.gui.androGui.PreferenceScreen;
import hu.bme.mit.androtext.nav.androNav.AbstractActivity;
import hu.bme.mit.androtext.nav.androNav.PreferenceActivity;
import hu.bme.mit.androtext.nav.androNav.SimpleImage;
import hu.bme.mit.androtext.nav.androNav.TabActivity;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;

public class ExtensionUtilDelegate {

	private static IAppGenerator generator;

	public ExtensionUtilDelegate() {
	}

	public static void setGenerator(IAppGenerator generator) {
		ExtensionUtilDelegate.generator = generator;
	}

	public static IAppGenerator getGenerator() {
		return generator;
	}

	/**
	 * Loads and returns the model based on the given parameter: uri.
	 * 
	 * @throws AppGenerationException
	 */
	public static EObject getResourceRoot(String uri)
			throws AppGenerationException {
		if (uri != null) {
			return generator.getResourceRoot(generator.getModelProject()
					.getFile(uri));
		}
		return null;
	}

	/**
	 * Returns the package name declared in the application age model.
	 * 
	 * @return
	 */
	public static String getApplicationPackageName() {
		return generator.getAndroidApplication().getPackageName();
	}

	public static String getApplicationName() {
		return generator.getAndroidApplication().getApplicationName();
	}

	public static String getSchema() {
		return "xmlns:android=\"http://schemas.android.com/apk/res/android\"";
	}

	public static List<Preference> getPreferences(AndroGuiRoot root) {
		List<Preference> preferences = new ArrayList<Preference>();
		if (root.getRootlayout() instanceof PreferenceScreen) {
			preferences = getPreferencesFromPreferenceScreen((PreferenceScreen) root
					.getRootlayout());
		}
		return preferences;
	}

	private static List<Preference> getPreferencesFromPreferenceScreen(
			PreferenceScreen screen) {
		List<Preference> preferences = new ArrayList<Preference>();
		for (Preference pref : screen.getPreferences()) {
			if (pref instanceof PreferenceScreen) {
				// pref screen
				preferences
						.addAll(getPreferencesFromPreferenceScreen((PreferenceScreen) pref));
			} else {
				// pref category
				if (pref instanceof PreferenceCategory) {
					preferences
							.addAll(getPreferencesFromPreferenceCategory((PreferenceCategory) pref));
				} else {
					// single preference
					preferences.add(pref);
				}
			}
		}
		return preferences;
	}

	private static List<Preference> getPreferencesFromPreferenceCategory(
			PreferenceCategory category) {
		List<Preference> preferences = new ArrayList<Preference>();
		for (Preference pref : category.getPreferences()) {
			if (pref instanceof PreferenceScreen) {
				// pref screen
				preferences
						.addAll(getPreferencesFromPreferenceScreen((PreferenceScreen) pref));
			} else {
				// pref category
				if (pref instanceof PreferenceCategory) {
					preferences
							.addAll(getPreferencesFromPreferenceCategory((PreferenceCategory) pref));
				} else {
					// single preference
					preferences.add(pref);
				}
			}
		}
		return preferences;
	}

	public static Boolean isXml(EObject o) {
		if (o instanceof AndroGuiRoot) {
			if (((AndroGuiRoot) o).getRootlayout() instanceof PreferenceScreen) {
				return true;
			}
		}
		return false;
	}

	/**
	 * All activity class name must be equal with the one in the AndroidSDK.
	 * 
	 * @param a
	 * @return
	 */
	public static String getBaseClass(AbstractActivity a) {
		if (a instanceof TabActivity) {
			return "TabActivity";
		}
		if (a instanceof PreferenceActivity) {
			return "PreferenceActivity";
		}
		return "Activity";
	}

	public static String getContentViewSet(AbstractActivity a) {
		String layoutName = getLayoutFileName(a.getName());
		if (a instanceof PreferenceActivity) {
			return "addPreferencesFromResource(R.xml." + layoutName + ");";
		}
		return "setContentView(R.layout." + layoutName + ");";
	}

	public static String getBaseClassFQN(AbstractActivity a) {
		if (a instanceof TabActivity) {
			return "android.app.TabActivity";
		}
		if (a instanceof PreferenceActivity) {
			return "android.preference.PreferenceActivity";
		}
		return "android.app.Activity";
	}

	public static String getLayoutFileName(String activityName) {
		return activityName.toLowerCase() + "_layout";
	}

	public static String getColumnType(Feature f) {
		TypeRef t = f.getType();
		if (t instanceof EntityTypeRef) {
			// one-to-one, many to many columns must have INTEGER as type for
			// foreign key
			return "INTEGER";
		}
		if (t instanceof DataTypeRef) {
			switch (((DataTypeRef) t).getReferencedDataType()) {
			case STRING:
				return "TEXT";
			case BOOLEAN:
				return "BOOLEAN";
			case FLOAT:
				return "REAL";
			case INT:
				return "INTEGER";
			}
		}
		throw new IllegalArgumentException("Unresolved column type!");
	}
	
	public static String getLayoutStyle(LayoutStyle e) {
		StringBuffer ret = new StringBuffer();
		String widthAttr = "android:layout_width";
		String heightAttr = "android:layout_height";
		String width = "";
		String height = "";
		switch (e) {
		case FILL:
			width = "fill_parent";
			height = "fill_parent";
			break;
		case FILL_WRAP:
			width = "fill_parent";
			height = "wrap_content";
			break;
		case WRAP:
			width = "wrap_content";
			height = "wrap_content";
			break;
		case WRAP_FILL:
			width = "wrap_content";
			height = "fill_parent";
			break;
		}
		ret.append(widthAttr);
		ret.append("=");
		ret.append("\""+width+"\"");
		ret.append(" ");
		ret.append(heightAttr);
		ret.append("=");
		ret.append("\""+height+"\"");
		return ret.toString();
	}
	
	public static void copy(SimpleImage i) {
		IFolder target = generator.getProject().getFolder(new Path(AndroidConstants2.RES_DIRECTORY + AndroidConstants2.DRAWABLE_MDPI_DIRECTORY));
		String path = i.getImportedURI();
		URI uri = CommonPlugin.resolve(URI.createURI(path));
		try {
			IFile[] f = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new java.net.URI(uri.toString()));
			if (f.length == 1) {
				f[0].copy(target.getFullPath().append("/" + f[0].getName()), true, null);
				System.out.println("" + f[0].getName() + "copied to destination!");
			} else {
				System.err.println("More files found!");
			}
		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}
}
